package com.puzzlebazar.server;

import com.puzzlebazar.client.puzzleinfo.PuzzleInfo.Status;
import com.puzzlebazar.client.user.UserInfo;
import com.puzzlebazar.server.PuzzleListFilter.Type;

public class CapabilitiesServer {
	
	/**
	 * Creates a JDO filter to retrieve editable puzzles
	 * 
	 * IMPORTANT: Keep in sync with Capabilites.canEditPuzzle
	 * 
	 * @param userInfo The user that should have the right to edit these puzzles
	 * return The filter
	 * @throws Exception
	 */
	static public PuzzleListFilter canEditPuzzleFilter( UserInfo userInfo ) throws Exception {
		PuzzleListFilter filter = new PuzzleListFilterBasic();
		filter.setType( Type.PUZZLE_ONLY );
		filter.addStatus( Status.PRIVATE );
		if( userInfo == null ) 
			throw new Exception( "Invalid user" );
		if( userInfo.isAdministrator() ) 
			return filter;
		filter.setAuthorEmail( userInfo.getEmail() );

		return filter;
	}
	

	/**
	 * Creates a JDO filter to retrieve playable puzzles
	 * 
	 * IMPORTANT: Keep in sync with Capabilites.canPlayPuzzle
	 * 
	 * @param userInfo The user that should have the right to play these puzzles
	 * @return The filter 
	 * @throws Exception
	 */
	static public PuzzleListFilter canPlayPuzzleFilter( UserInfo userInfo  ) throws Exception {
		if( userInfo != null && userInfo.isAdministrator() ) {
			PuzzleListFilterBasic filter = new PuzzleListFilterBasic();
			filter.setNeedModelInDatastore( true );
			filter.setType( Type.PUZZLE_ONLY );
			return filter;
		}

		CompositePuzzleListFilter filter = new CompositePuzzleListFilter();		

		PuzzleListFilter filterA = new PuzzleListFilterBasic();
		filterA.addStatus( Status.PUBLISHED );
		filterA.addStatus( Status.REVIEW_PUBLISHED );
		filter.add( filterA );

		if( userInfo != null ) {
			PuzzleListFilter filterB = new PuzzleListFilterBasic();
			filterB.setAuthorEmail( userInfo.getEmail() );
			filterB.addStatus( Status.PRIVATE );
			filterB.addStatus( Status.IN_REVIEW );
			filterB.addStatus( Status.ACCEPTED );
			filter.add( filterB );
		}
		
		filter.setNeedModelInDatastore( true );
		filter.setType( Type.PUZZLE_ONLY );
		
		return filter;
	}


	/**
	 * Creates a JDO filter to retrieve loadable puzzles
	 * 
	 * IMPORTANT: Keep in sync with Capabilites.canLoadPuzzle
	 * 
	 * @param userInfo The user that should have the right to load these puzzles
	 * @return The filter
	 * @throws Exception
	 */
	public static PuzzleListFilter canLoadPuzzleFilter(UserInfo userInfo) throws Exception {
		if( userInfo == null )
			return canPlayPuzzleFilter(userInfo);
		CompositePuzzleListFilter filter = new CompositePuzzleListFilter();
		filter.add( canEditPuzzleFilter(userInfo) );
		filter.add( canPlayPuzzleFilter(userInfo) );
		filter.setType( Type.PUZZLE_ONLY );

		return filter;

	}


	/**
	 * Creates a JDO filter to retrieve viewable tutorial
	 * 
	 * IMPORTANT: Keep in sync with Capabilites.canLoadTutorial
	 * 
	 * @param userInfo The user that should have the right to view these tutorials
	 * @return The filter
	 * @throws Exception
	 */
	public static PuzzleListFilter canViewTutorialFilter(UserInfo userInfo) throws Exception {
		PuzzleListFilter filter = new PuzzleListFilterBasic();
		filter.addStatus( Status.PUBLISHED );
		filter.addStatus( Status.REVIEW_PUBLISHED );
		filter.setNeedModelInDatastore( true );
		filter.setType( Type.TUTORIAL_ONLY );
		return filter;
	}


	/**
	 * Creates a JDO filter to retrieve editable tutorials
	 * 
	 * IMPORTANT: Keep in sync with Capabilites.canEditTutorial
	 * 
	 * @param userInfo The user that should have the right to edit these tutorials
	 * @return The filter
	 * @throws Exception
	 */
	public static PuzzleListFilter canEditTutorialFilter(UserInfo userInfo) throws Exception {
		PuzzleListFilter filter = new PuzzleListFilterBasic();
		filter.setType( Type.TUTORIAL_ONLY );
		filter.addStatus( Status.PRIVATE );
		if( userInfo == null ) 
			throw new Exception( "Invalid user" );
		if( userInfo.isAdministrator() ) 
			return filter;
		filter.setAuthorEmail( userInfo.getEmail() );
	
		return filter;
	}
}
